package basic.arch.component.lock.distributed.mysql;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import basic.arch.component.lock.aop.annotation.Lock.DisstributionLockType;
import basic.arch.component.lock.config.CurrentLockSettings;
import basic.arch.component.lock.distributed.DistributionLockSupport;
import basic.arch.component.lock.distributed.mysql.mapper.Lock;
import basic.arch.component.lock.distributed.mysql.service.LockService;

@Component("mysqlDistributionLock")
public class MysqlDistributionLock extends DistributionLockSupport{
    
    private Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private LockService lockService;
    
    @Value("${lock.mysql.releaselock.maxtime}")
    private long releaseLockMaxTime=60L;
    @Value("${lock.mysql.scan.interval.time}")
    private long scanMysqlIntervalTime=20L;
    
    private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

    @Override
    protected boolean acquire(CurrentLockSettings currentLockSettings) {
        return lockService.insertIfAbsent(currentLockSettings.getCurrenLockKey());
    }

    @Override
    public void unlock0(String key) {
      //如果删除失败或者在删除之前就已经宕机，此时导致锁无法释放,mysql的通过创建时间判断，是否超时
      lockService.deleteLock(key);
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        // 延迟一秒后 每5秒执行一次
        service.scheduleAtFixedRate(new DeleteKeyForToLock(), 1L, scanMysqlIntervalTime, TimeUnit.SECONDS);
    }
    
    public class DeleteKeyForToLock implements Runnable{

        @Override
        public void run() {
            List<Lock> lockList = lockService.findAll();
           if(lockList!=null&&lockList.size()>0){
               int size = lockList.size();
               Lock lock = null;
               Date createTime = null;
               for(int i =0;i<size;i++){
                  lock = lockList.get(i);
                  createTime = lock.getCreateTime();
                  long currentTime = new Date().getTime();
                  long time=currentTime-createTime.getTime()/1000;
                  if(time>releaseLockMaxTime){//releaseLockMaxTime秒内还未释放锁，就删除掉
                      try {
                          if (LOGGER.isDebugEnabled()) {
                              LOGGER.debug("开始清理key为{}的键", lock.getType());
                          }
                        lockService.deleteLock(lock.getType());
                    } catch (Exception e) {
                        LOGGER.error(e.getMessage(),e);
                    }
                  }
                  
               }
           }
        }
        
    }

    @Override
    public DisstributionLockType getType() {
        return DisstributionLockType.MYSQL;
    }


}
